<html>
<head><meta charset="utf-8"><title>Pre-RFC: saturating_shl/shr on integer types · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html">Pre-RFC: saturating_shl/shr on integer types</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="243114701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243114701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> avitex <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243114701">(Jun 18 2021 at 04:14)</a>:</h4>
<p>Hey folks, just want to ask if a <code>saturating_shl</code> / <code>saturating_shr</code> has been previously discussed that I can't find from searching github and here.<br>
I'm quite happy to write up an RFC. The idea would be if the amount of bits to shift by was equal or greater than the number of bits in the type it would return <code>0</code>.</p>



<a name="243130580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243130580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> avitex <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243130580">(Jun 18 2021 at 08:29)</a>:</h4>
<p>Looking for some feedback on: <a href="https://github.com/avitex/rfcs/blob/master/text/0000-saturating-bit-shifts.md">https://github.com/avitex/rfcs/blob/master/text/0000-saturating-bit-shifts.md</a> if possible. Thank you! :)</p>



<a name="243156878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243156878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243156878">(Jun 18 2021 at 13:01)</a>:</h4>
<p>I'd speak to libs-api, but it's likely that this change is so obvious and simple that an RFC wouldn't be needed. Usually adding single small methods can just go through an FCP on the PR that adds them to the Nightly standard library, without the entire formal RFC process.</p>



<a name="243180930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243180930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243180930">(Jun 18 2021 at 16:08)</a>:</h4>
<p><span class="user-mention" data-user-id="399889">@avitex</span> that's a very reasonable function to have. i'd be slightly worried about the name. just by the name i didn't directly grasp what it'd do, but it does make sense in some ways and i can't think of a better name right now.</p>



<a name="243181110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243181110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243181110">(Jun 18 2021 at 16:10)</a>:</h4>
<p>I've never been super happy with applying these conventions to shl/shr, since talking about the shift amount instead of the result is a bit weird to me, given how these apply to <code>add</code> and <code>mul</code> and such.</p>
<p>Having a shift that "just works" (so <code>&gt;&gt;N</code> is the same as doing <code>&gt;&gt;1</code> N times) seems very reasonable.  But it's not obvious to me that <code>saturating_</code> is the name for it -- I think one could reasonably assuming that <code>x.saturating_shr(1000)</code> would give <code>x &gt;&gt; 31</code>, not <code>0</code>, because of saturating the shift amount into an <code>i5</code>.</p>



<a name="243181111"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243181111" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243181111">(Jun 18 2021 at 16:10)</a>:</h4>
<p><span class="user-mention" data-user-id="399889">@avitex</span> x.saturating_shr(10000) would produce <code>-1</code> and not <code>0</code> for negative x, i assume?</p>



<a name="243181281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243181281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Notification Bot <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243181281">(Jun 18 2021 at 16:12)</a>:</h4>
<p>This topic was moved here from <a class="stream-topic" data-stream-id="122651" href="/#narrow/stream/122651-general/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types">#general &gt; Pre-RFC: saturating_shl/shr on integer types</a> by <span class="user-mention silent" data-user-id="310399">Mara</span></p>



<a name="243181319"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243181319" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243181319">(Jun 18 2021 at 16:12)</a>:</h4>
<p>Spitballing: <code>2.signed_shl(-1) =&gt; 1</code></p>
<p>EDIT: no, I don't like that any more.  Gives too much of an <em>A</em>SHL vibe.</p>



<a name="243181453"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243181453" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243181453">(Jun 18 2021 at 16:14)</a>:</h4>
<p>So I guess we're doing an "infinite precision" shift and keeping the value that fits back in range of the type, is one way to think about it. Though that doesn't suggest a better name offhand.</p>



<a name="243193219"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243193219" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243193219">(Jun 18 2021 at 18:12)</a>:</h4>
<p>what about signed ints?</p>



<a name="243195530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243195530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243195530">(Jun 18 2021 at 18:40)</a>:</h4>
<p>For this operation, it's consistent to think of the conversion from the limited precision type to the temporary infinite precision type as being the "natural" way you convert an integer to a higher bit integer sign-ness.</p>
<p>In other words:</p>
<ul>
<li>uX to u(X+N) is always 0-extended when increasing the bit count.</li>
<li>iX to i(X+N) is always sign-extended when increasing the bit count.</li>
</ul>
<p>So if you imagine it as being a "bit increase" to infinity bits, then the operation, then a truncation to the original size, you'll get the "correct" results:</p>
<ul>
<li>unsigned values shift in 0s on either side.</li>
<li>signed values shift in 0s on the low end and sign bits on the high end.</li>
</ul>



<a name="243235725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243235725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243235725">(Jun 19 2021 at 07:45)</a>:</h4>
<p><a href="https://lists.llvm.org/pipermail/llvm-dev/2020-July/143195.html">https://lists.llvm.org/pipermail/llvm-dev/2020-July/143195.html</a> LLVM's sat shl returns MIN or MAX, as appropriate, if the saturating condition is triggered, not 0.</p>



<a name="243245588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243245588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243245588">(Jun 19 2021 at 11:42)</a>:</h4>
<p>so <code>0b1000_0000u8.saturating_shl(1) == 0xFF</code>?</p>



<a name="243262723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243262723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243262723">(Jun 19 2021 at 18:27)</a>:</h4>
<p>The proposed behavior is <code>0b1000_0000u8.saturating_shl(1) == 0</code>. <code>0b1000_0000u8.saturating_shl(1) == 0xFF</code> would be diabolical</p>



<a name="243262773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243262773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243262773">(Jun 19 2021 at 18:28)</a>:</h4>
<p>but I think it indicates that <code>saturating_*</code> is not the right name</p>



<a name="243262774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243262774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243262774">(Jun 19 2021 at 18:28)</a>:</h4>
<p>can we just call this <code>shl()</code>? This is the bitshift that god intended</p>



<a name="243263166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243263166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243263166">(Jun 19 2021 at 18:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243262774">said</a>:</p>
<blockquote>
<p>can we just call this <code>shl()</code>? This is the bitshift that god intended</p>
</blockquote>
<p>No, because if one <code>use std::ops::Shl;</code> then there's already a <code>shl</code>.</p>



<a name="243263192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243263192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243263192">(Jun 19 2021 at 18:39)</a>:</h4>
<p>what does the normal shl do?</p>



<a name="243263379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243263379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243263379">(Jun 19 2021 at 18:44)</a>:</h4>
<p>checks the shift amount in debug, wraps it in release.</p>



<a name="243263468"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243263468" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243263468">(Jun 19 2021 at 18:47)</a>:</h4>
<p>ugh... I see the consistency argument but this seems like a misunderstanding of what overflow means in the context of bitshifts</p>



<a name="243263532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243263532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243263532">(Jun 19 2021 at 18:48)</a>:</h4>
<p>how about <code>unbounded_shl</code>?</p>



<a name="243266383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243266383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243266383">(Jun 19 2021 at 20:02)</a>:</h4>
<blockquote>
<p>0b1000_0000u8.saturating_shl(1) == 0xFF would be diabolical</p>
</blockquote>
<p>that's what llvm does, as Jubilee mentioned</p>



<a name="243266453"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243266453" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243266453">(Jun 19 2021 at 20:03)</a>:</h4>
<p>i'm wondering what happens if we just make regular <code>&lt;&lt;</code> and <code>&gt;&gt;</code> work with larger shifts. no panics, no wrapping in release mode. just use .wrapping_shl() if you want to avoid the check.</p>



<a name="243267521"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243267521" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243267521">(Jun 19 2021 at 20:29)</a>:</h4>
<p>I would really really like this, but I fear it would fall afoul of some backward compatibility guarantee that even editions couldn't address</p>



<a name="243267613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243267613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243267613">(Jun 19 2021 at 20:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243245588">said</a>:</p>
<blockquote>
<p>so <code>0b1000_0000u8.saturating_shl(1) == 0xFF</code>?</p>
</blockquote>
<p>Correct.</p>



<a name="243267694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243267694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243267694">(Jun 19 2021 at 20:33)</a>:</h4>
<p>and yes, this is kind of like an <code>infinite_shl</code></p>



<a name="243267697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243267697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243267697">(Jun 19 2021 at 20:33)</a>:</h4>
<p>or unbounded or w/e</p>



<a name="243267971"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243267971" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243267971">(Jun 19 2021 at 20:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243262723">said</a>:</p>
<blockquote>
<p>The proposed behavior is <code>0b1000_0000u8.saturating_shl(1) == 0</code>. <code>0b1000_0000u8.saturating_shl(1) == 0xFF</code> would be diabolical</p>
</blockquote>
<p>It turns out that Arm's A32/T32 is quite diabolical:<br>
<a href="https://developer.arm.com/documentation/ddi0597/2020-12/Base-Instructions/USAT--Unsigned-Saturate-">https://developer.arm.com/documentation/ddi0597/2020-12/Base-Instructions/USAT--Unsigned-Saturate-</a></p>



<a name="243287652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243287652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243287652">(Jun 20 2021 at 05:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243266453">said</a>:</p>
<blockquote>
<p>i'm wondering what happens if we just make regular <code>&lt;&lt;</code> and <code>&gt;&gt;</code> work with larger shifts. no panics, no wrapping in release mode. just use .wrapping_shl() if you want to avoid the check.</p>
</blockquote>
<p>sounds like you'd break someone, somehow, to change it at this point.</p>
<p><span class="user-mention silent" data-user-id="281757">Jubilee</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243267694">said</a>:</p>
<blockquote>
<p>and yes, this is kind of like an <code>infinite_shl</code></p>
</blockquote>
<p>please, please, call it the "infinite shift".</p>



<a name="243288799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243288799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243288799">(Jun 20 2021 at 06:12)</a>:</h4>
<p>What should this do with negative shift amounts?  Or will it only take unsigned?</p>



<a name="243288811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243288811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243288811">(Jun 20 2021 at 06:13)</a>:</h4>
<p>It's probably safer to just use unsigned shift amounts, but for signed shift the obvious choice is to shift the other way</p>



<a name="243288858"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243288858" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243288858">(Jun 20 2021 at 06:15)</a>:</h4>
<p>both are preferable to UB/panic/wrap</p>



<a name="243387253"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243387253" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243387253">(Jun 21 2021 at 14:07)</a>:</h4>
<blockquote>
<p>sounds like you'd break someone, somehow, to change it at this point.</p>
</blockquote>
<p>but the current behaviour is already a <em>panic</em> in debug mode, but not in release mode. depending on <em>that</em> is a bit hard to imagine.</p>



<a name="243395297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243395297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243395297">(Jun 21 2021 at 15:00)</a>:</h4>
<p>Well, more precisely, it's to panic or not based on the <code>overflow-checks</code> flag, which defaults as you say, but I know that I've altered the default setting in several projects here and there over the years. Usually to turn them off in all build profiles.</p>



<a name="243395931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243395931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243395931">(Jun 21 2021 at 15:04)</a>:</h4>
<p>It certainly might actually be fine, because i don't think dynamic shift amounts are particularly popular to begin with, but my gut tells me that a crater run or an edition line might be appropriate</p>



<a name="243396744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243396744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> LingM <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243396744">(Jun 21 2021 at 15:09)</a>:</h4>
<p>As a data point, <a href="https://github.com/rust-lang/rust/issues/72895#issuecomment-670677002">here</a> someone thought <code>&gt;&gt;</code> already shifts in arbitrary many zeros. I thought the same until that post caused me to check the docs. My gut feeling is that by changing <code>&gt;&gt;</code> there are far more people who use it incorrectly right now that you'll unbreak than there are people who rely on the current behaviour.</p>
<p>(as <span class="user-mention" data-user-id="224471">@Lokathor</span> just mentioned while I typed this, a crater run is certainly in order to get a better data basis)</p>



<a name="243405740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243405740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243405740">(Jun 21 2021 at 16:11)</a>:</h4>
<p>How do you do a crater run for this though? It's a behavior change, not a compilation change</p>



<a name="243405908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243405908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243405908">(Jun 21 2021 at 16:12)</a>:</h4>
<p>I guess crater does <code>cargo test</code> under some configurations, which might catch some behavior changes, but it seems like rather poor coverage</p>



<a name="243408273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243408273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243408273">(Jun 21 2021 at 16:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="296422">LingM</span> <a href="#narrow/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types/near/243396744">said</a>:</p>
<blockquote>
<p>My gut feeling is that by changing <code>&gt;&gt;</code> there are far more people who use it incorrectly right now that you'll unbreak than there are people who rely on the current behaviour.</p>
</blockquote>
<p>Even assuming that's true, I'm not a fan -- I don't want to penalize people doing it correctly because others are doing it wrong.  (Especially since default debug mode will catch that they're doing it wrong.)</p>



<a name="243408640"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243408640" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243408640">(Jun 21 2021 at 16:34)</a>:</h4>
<p>for + we already expect people to use .wrapping_add() if they really want the wrapping case. and i'm not sure if adding the extra check to <code>&gt;&gt;</code> really matters. i would expect in almost all cases that the compiler can prove it's less than the total number of bits (because it comes from leading_zeros() or it is a constant or something)</p>



<a name="243409371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243409371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243409371">(Jun 21 2021 at 16:41)</a>:</h4>
<p>(well, <code>&lt;&lt; leading_ones()</code> is only guaranteed in-bounds on a <code>NonZero</code>, but yes.  The constant shift feels like it's by far the common case.)</p>



<a name="243414677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243414677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243414677">(Jun 21 2021 at 17:23)</a>:</h4>
<p>sure. but leading_zeros() already has a zero check. so then that same check would skip over the relevant &lt;&lt; part.</p>



<a name="243421486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Pre-RFC%3A%20saturating_shl/shr%20on%20integer%20types/near/243421486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Pre-RFC.3A.20saturating_shl.2Fshr.20on.20integer.20types.html#243421486">(Jun 21 2021 at 18:13)</a>:</h4>
<p>I've definitely had cases where I wanted the infinite precision behavior when working with data-dependent shifts and only got reminded of the current behavior once tests failed.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>